﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;

namespace JV.Com.Tools
{
    public class HtmlToRichTextConverter
    {
        public enum ConvertType
        {
            News,
            Test,
            Preview,
            TestRecap,
            Folder,
            FolderPage
        }

        private class HtmlContext
        {
            public HTMLImageCollection ImageCollection { get; set; }
        }

        private bool m_firstStrong;
        private bool m_firstH2;


        private readonly ConvertType m_type;
        private readonly HTMLInlineCollection m_inlines;
        private readonly HtmlContext m_parsingContext;

        public HtmlToRichTextConverter(ConvertType type)
        {
            m_type = type;
            m_firstStrong = true;
            m_firstH2 = true;
            m_inlines = new HTMLInlineCollection();
            m_parsingContext = new HtmlContext();
        }

        public HTMLInlineCollection GetHTMLInlineCollection(string html)
        {
            var document = new HtmlDocument();
            document.LoadHtml(html);
            var rootNode = document.DocumentNode;

            FillCollectionWith(rootNode);
            m_inlines.Process();

            return m_inlines;
        }

        private void FillCollectionWith(HtmlNode node)
        {
            if(m_type == ConvertType.TestRecap)
            {
                if (node.Name == "div")
                {
                    var attrId = node.Attributes["id"];
                    var attrClass = node.Attributes["class"];

                    if (attrClass != null)
                    {
                        if (new[] { "avis_infos", "note", "resume" }.Contains(attrClass.Value))
                        {
                            return;
                        }
                    }
                }
                else if(node.Name == "li" && !string.IsNullOrEmpty(node.InnerText))
                {
                    var text = node.InnerText;
                    if(text[0] != '-')
                    {
                        text = text.Insert(0, "- ");
                        m_inlines.AddInline(new HTMLDefaultText() { Text = text });
                        return;
                    }
                }
            }

            if (node.Name == "table") return;

            if (node.Name == "div" && node.Attributes["class"] != null && node.Attributes["class"].Value == "serie_img")
            {
                m_parsingContext.ImageCollection = new HTMLImageCollection();
                m_inlines.AddLineBreak();
                foreach(var elem in node.ChildNodes)
                {
                    FillCollectionWith(elem);
                }
                m_inlines.AddInline(m_parsingContext.ImageCollection);
                m_inlines.AddLineBreak();
                m_parsingContext.ImageCollection = null;
            }
            else if (node.Name == "h3")
            {
                if (node.ChildNodes.Any(c => c.Name == "a"))
                {
                    foreach (var elem in node.ChildNodes)
                    {
                        FillCollectionWith(elem);
                    }
                }
                else
                {
                    m_inlines.AddInline(new HTMLTitle() { Text = node.InnerText, ImportanceValue = HTMLTitle.Importance.Big });
                    if (m_type == ConvertType.FolderPage)
                    {
                        m_inlines.AddLineBreak();
                    }
                }
            }
            else if (node.Name == "h2")
            {
                if(m_type == ConvertType.TestRecap)
                {
                    return;
                }
                else if(m_type == ConvertType.FolderPage && m_firstH2)
                {
                    m_firstH2 = false;
                    return;
                }

                m_inlines.AddInline(new HTMLTitle() { Text = node.InnerText, ImportanceValue = HTMLTitle.Importance.Medium });
                m_inlines.AddLineBreak();

                m_firstH2 = false;
            }
            else if (node.Name == "p")
            {
                if (node.Attributes["class"] != null && node.Attributes["class"].Value == "centrer")
                {
                    m_inlines.AddInline(new HTMLTitle() { Text = node.InnerText, ImportanceValue = HTMLTitle.Importance.Big });
                }
                else if (node.InnerText == "&#160;")
                {
                    m_inlines.AddLineBreak();
                }
                else if(node.Attributes["class"] != null && node.Attributes["class"].Value.Contains("test_encart"))
                {
                    var flt = node.Attributes["class"].Value;
                    var img = node.ChildNodes.First(c => c.Name == "a").ChildNodes.First(c => c.Name == "img");
                    var src = img.Attributes["src"].Value;
                    string bigSrc = null;
                    if (img.ParentNode.Name == "a")
                    {
                        bigSrc = img.ParentNode.Attributes["href"].Value;
                    }
                    m_inlines.AddInline(new HTMLImage()
                    {
                        FloatingValue = flt.Contains("gauche") ? HTMLImageFloating.Left : HTMLImageFloating.Right,
                        ImageUrl = src,
                        LargeImageUrl = bigSrc
                    });
                }
                else if (node.Attributes["class"] != null && node.Attributes["class"].Value == "player")
                {
                    var videoLink = node.FirstChild.Attributes["href"].Value;
                    //var videoLinkSplited = videoLink.Split('-');
                    //var firstVideoLink = new StringBuilder();
                    //for (int i = 0; i < videoLinkSplited.Length - 1; i++)
                    //{
                    //    firstVideoLink.Append(videoLinkSplited[i]);
                    //    firstVideoLink.Append("-");
                    //}

                    var image = node.FirstChild.FirstChild.Attributes["src"].Value;
                    m_inlines.AddInline(new HTMLMediaElement() { VideoUrl = videoLink.ToString(), ImageUrl = image });
                    m_inlines.AddLineBreak();
                }
                else
                {
                    foreach (var elem in node.ChildNodes)
                    {
                        FillCollectionWith(elem);
                    }

                    m_inlines.AddLineBreak();
                }
            }
            else if(node.Name == "ul")
            {
                if(node.Attributes["class"] != null && node.Attributes["class"].Value == "encartvideo")
                {
                    foreach (var elem in node.ChildNodes)
                    {
                        var title = elem.FirstChild.InnerText;
                        m_inlines.AddInline(new HTMLTitle() { Text = title, ImportanceValue = HTMLTitle.Importance.Medium });
                        m_inlines.AddLineBreak();
                        var link = elem.ChildNodes.First(c => c.Name == "a").Attributes["href"].Value;
                        m_inlines.AddInline(new HTMLMediaElement() { VideoUrl = link });
                        m_inlines.AddLineBreak();
                    }
                }
                else
                {
                    foreach (var elem in node.ChildNodes)
                    {
                        FillCollectionWith(elem);
                    }
                }
            }
            else if (node.Name == "strong")
            {
                if (m_firstStrong)
                {
                    m_firstStrong = false;
                    if(m_type == ConvertType.News)
                    {
                        return;
                    }
                }
                
                if(m_type == ConvertType.TestRecap)
                {
                    m_inlines.AddInline(new HTMLTitle() { Text = node.InnerText, ImportanceValue = HTMLTitle.Importance.Big });
                }
                else if (m_parsingContext.ImageCollection != null)
                {
                    m_inlines.AddInline(new HTMLTitle() { Text = node.InnerText, ImportanceValue = HTMLTitle.Importance.Medium });
                    m_inlines.AddLineBreak();
                }
                else
                {
                    m_inlines.AddInline(new HTMLStrongText() { Text = node.InnerText });
                }
            }
            else if (node.Name == "#text")
            {
                foreach(var inline in HTMLText.ConvertToParagraph(node.InnerText))
                {
                    m_inlines.AddInline(inline);
                }
            }
            else if (node.Name == "a")
            {
                if (node.ChildNodes.Count == 1 && node.ChildNodes[0].NodeType == HtmlNodeType.Text)
                {
                    var url = node.Attributes["href"].Value;
                    m_inlines.AddInline(new HTMLHyperLink() { Text = node.InnerText, Url = url });
                }
                else
                {
                    foreach (var elem in node.ChildNodes)
                    {
                        FillCollectionWith(elem);
                    }
                }
            }
            else if (node.Name == "img")
            {
                var src = node.Attributes["src"].Value;
                string bigSrc = null;
                if(node.ParentNode.Name == "a")
                {
                    var target = node.ParentNode.Attributes["target"];
                    if (target == null || target != null && target.Value != "profil")
                    {
                        bigSrc = node.ParentNode.Attributes["href"].Value;
                    }
                }

                if (m_parsingContext.ImageCollection != null)
                {
                    m_parsingContext.ImageCollection.AddImage(new HTMLImage() { ImageUrl = src, FloatingValue = HTMLImageFloating.None, LargeImageUrl = bigSrc });
                }
                else
                {
                    var flt = string.Empty;
                    if (node.Attributes["class"] != null)
                        flt = node.Attributes["class"].Value;

                    var image = new HTMLImage() { ImageUrl = src, LargeImageUrl = bigSrc };
                    if (flt.Contains("img_g"))
                    {
                        image.FloatingValue = HTMLImageFloating.Left;
                    }
                    else if (flt.Contains("img_d"))
                    {
                        image.FloatingValue = HTMLImageFloating.Right;
                    }
                    else
                    {
                        image.FloatingValue = HTMLImageFloating.None;
                    }

                    m_inlines.AddInline(image);
                }
            }
            else
            {
                foreach (var elem in node.ChildNodes)
                {
                    FillCollectionWith(elem);
                }

                if (node.Name == "div")
                {
                    m_inlines.AddLineBreak();
                }
            }
        }
    }
}
